package core

import (
	"gitee.com/feimos/dm/utils"
	"log"
	"sort"
	"strconv"
	"time"
)

const LastTableName string = "TOTAL"

type OverviewItem struct {
	Name  string
	Count int
	Size  int64
	Time  time.Time
}

type OverviewResult struct {
	SumCount   int
	SumSize    int64
	LatestTime time.Time
	Item       []OverviewItem
}

type TimeSortOverviewResult OverviewResult

type SizeSortOverviewResult OverviewResult

type CountSortOverviewResult OverviewResult

func (t TimeSortOverviewResult) Len() int {
	return len(t.Item)
}

func (t TimeSortOverviewResult) Less(i, j int) bool {
	timeI := t.Item[i].Time
	timeJ := t.Item[j].Time

	timeI.After(timeJ)
	return timeI.After(timeJ)
}

func (t TimeSortOverviewResult) Swap(i, j int) {
	t.Item[i], t.Item[j] = t.Item[j], t.Item[i]
}

func (s SizeSortOverviewResult) Len() int {
	return len(s.Item)
}

func (s SizeSortOverviewResult) Less(i, j int) bool {

	return s.Item[i].Size-s.Item[j].Size > 0
}

func (s SizeSortOverviewResult) Swap(i, j int) {
	s.Item[i], s.Item[j] = s.Item[j], s.Item[i]
}

func (c CountSortOverviewResult) Len() int {
	return len(c.Item)
}

func (c CountSortOverviewResult) Less(i, j int) bool {

	return c.Item[i].Count-c.Item[j].Count > 0
}

func (c CountSortOverviewResult) Swap(i, j int) {
	c.Item[i], c.Item[j] = c.Item[j], c.Item[i]
}

func GenerateOverviewByExt(yamlContent *YamlContent, extName string) OverviewResult {

	count := 1
	globalCount := 0
	var res OverviewResult
	var globalSizeSum int64
	var globalLatestTime time.Time

	if infos, ok := yamlContent.Nodes[extName]; ok {
		var sumSize int64
		var latestTime time.Time

		for index, info := range infos {
			if index == 0 {
				latestTime = info.Time
				if globalLatestTime.IsZero() {
					globalLatestTime = latestTime
				}
			} else {
				if info.Time.After(latestTime) {
					latestTime = info.Time
				}
			}

			if info.Time.After(globalLatestTime) {
				globalLatestTime = info.Time
			}
			sumSize += info.Size

			item := OverviewItem{
				Size: info.Size,
				Time: info.Time,
				Name: info.Name,
			}

			res.Item = append(res.Item, item)
		}

		globalCount += len(infos)
		globalSizeSum += sumSize

		count++
	} else {
		log.Fatalf("ext name \"%v\" is not existed in the root\n", extName)
	}

	res.SumCount = globalCount
	res.SumSize = globalSizeSum
	res.LatestTime = globalLatestTime
	return res
}

func GenerateOverview(yamlContent *YamlContent) OverviewResult {

	count := 1
	globalCount := 0
	var res OverviewResult
	var globalSizeSum int64
	var globalLatestTime time.Time

	for ext, infos := range yamlContent.Nodes {

		var sumSize int64
		var latestTime time.Time

		for index, info := range infos {
			if index == 0 {
				latestTime = info.Time
				if globalLatestTime.IsZero() {
					globalLatestTime = latestTime
				}
			} else {
				if info.Time.After(latestTime) {
					latestTime = info.Time
				}
			}

			if info.Time.After(globalLatestTime) {
				globalLatestTime = info.Time
			}
			sumSize += info.Size
		}

		globalCount += len(infos)
		globalSizeSum += sumSize

		item := OverviewItem{
			Count: len(infos),
			Size:  sumSize,
			Time:  latestTime,
			Name:  ext,
		}

		res.Item = append(res.Item, item)
		count++
	}

	res.SumCount = globalCount
	res.SumSize = globalSizeSum
	res.LatestTime = globalLatestTime
	return res
}

func SortOverviewData(result OverviewResult, timeSort int, sizeSort int, countSort int, extName string) [][]string {

	var res [][]string
	if timeSort < 0 {
		sort.Sort(TimeSortOverviewResult(result))
	} else if timeSort > 0 {
		sort.Sort(sort.Reverse(TimeSortOverviewResult(result)))
	}

	if sizeSort < 0 {
		sort.Sort(SizeSortOverviewResult(result))
	} else if sizeSort > 0 {
		sort.Sort(sort.Reverse(SizeSortOverviewResult(result)))
	}

	if len(extName) == 0 {
		if countSort < 0 {
			sort.Sort(CountSortOverviewResult(result))
		} else if countSort > 0 {
			sort.Sort(sort.Reverse(CountSortOverviewResult(result)))
		}
	}

	for index, overviewItem := range result.Item {

		if len(extName) == 0 {
			item := make([]string, 5)

			item[0] = strconv.Itoa(index + 1)
			item[1] = overviewItem.Name
			item[2] = strconv.Itoa(overviewItem.Count)
			item[3] = utils.FormatFileSize(overviewItem.Size)
			item[4] = utils.SubString(overviewItem.Time.String(), 19)
			res = append(res, item)
		} else {
			item := make([]string, 4)

			item[0] = strconv.Itoa(index + 1)
			item[1] = overviewItem.Name
			item[2] = utils.FormatFileSize(overviewItem.Size)
			item[3] = utils.SubString(overviewItem.Time.String(), 19)
			res = append(res, item)
		}
	}

	if len(extName) == 0 {
		index := "*"
		// index := strconv.Itoa(len(result.Item) + 1)
		res = append(res, []string{index, LastTableName, strconv.Itoa(result.SumCount), utils.FormatFileSize(result.SumSize), utils.SubString(result.LatestTime.String(), 19)})

	} else {
		index := "*"
		// index := strconv.Itoa(len(result.Item) + 1)
		res = append(res, []string{index, LastTableName, utils.FormatFileSize(result.SumSize), utils.SubString(result.LatestTime.String(), 19)})

	}

	return res
}
